package api

import (
	"encoding/json"
	"net/http"
	"time"

	"github.com/sirupsen/logrus"
)

// Response 统一的API响应格式
type Response struct {
	Success   bool        `json:"success"`
	Data      interface{} `json:"data,omitempty"`
	Error     *ErrorInfo  `json:"error,omitempty"`
	Meta      *Meta       `json:"meta,omitempty"`
	Timestamp int64       `json:"timestamp"`
	RequestID string      `json:"requestId,omitempty"`
}

// ErrorInfo 错误信息
type ErrorInfo struct {
	Code    string                 `json:"code"`
	Message string                 `json:"message"`
	Details map[string]interface{} `json:"details,omitempty"`
	Stack   string                 `json:"stack,omitempty"` // 仅在开发环境显示
}

// Meta 元数据
type Meta struct {
	Page       int    `json:"page,omitempty"`
	PerPage    int    `json:"perPage,omitempty"`
	Total      int64  `json:"total,omitempty"`
	TotalPages int    `json:"totalPages,omitempty"`
	Version    string `json:"version,omitempty"`
}

// PaginatedData 分页数据
type PaginatedData struct {
	Items interface{} `json:"items"`
	Meta  *Meta       `json:"meta"`
}

// ResponseBuilder 响应构建器
type ResponseBuilder struct {
	response  *Response
	logger    *logrus.Logger
	isDev     bool
	requestID string
}

// NewResponseBuilder 创建响应构建器
func NewResponseBuilder(logger *logrus.Logger, isDev bool) *ResponseBuilder {
	return &ResponseBuilder{
		response: &Response{
			Timestamp: time.Now().UnixMilli(),
		},
		logger: logger,
		isDev:  isDev,
	}
}

// WithRequestID 设置请求ID
func (rb *ResponseBuilder) WithRequestID(id string) *ResponseBuilder {
	rb.requestID = id
	rb.response.RequestID = id
	return rb
}

// Success 构建成功响应
func (rb *ResponseBuilder) Success(data interface{}) *Response {
	rb.response.Success = true
	rb.response.Data = data

	rb.logger.WithFields(logrus.Fields{
		"requestId": rb.requestID,
		"success":   true,
	}).Debug("API response")

	return rb.response
}

// SuccessWithMeta 构建带元数据的成功响应
func (rb *ResponseBuilder) SuccessWithMeta(data interface{}, meta *Meta) *Response {
	rb.response.Success = true
	rb.response.Data = data
	rb.response.Meta = meta

	rb.logger.WithFields(logrus.Fields{
		"requestId": rb.requestID,
		"success":   true,
		"meta":      meta,
	}).Debug("API response with meta")

	return rb.response
}

// Paginated 构建分页响应
func (rb *ResponseBuilder) Paginated(items interface{}, page, perPage int, total int64) *Response {
	totalPages := int((total + int64(perPage) - 1) / int64(perPage))

	meta := &Meta{
		Page:       page,
		PerPage:    perPage,
		Total:      total,
		TotalPages: totalPages,
	}

	rb.response.Success = true
	rb.response.Data = &PaginatedData{
		Items: items,
		Meta:  meta,
	}

	rb.logger.WithFields(logrus.Fields{
		"requestId":  rb.requestID,
		"success":    true,
		"page":       page,
		"perPage":    perPage,
		"total":      total,
		"totalPages": totalPages,
	}).Debug("API paginated response")

	return rb.response
}

// Error 构建错误响应
func (rb *ResponseBuilder) Error(code, message string, details map[string]interface{}) *Response {
	rb.response.Success = false
	rb.response.Error = &ErrorInfo{
		Code:    code,
		Message: message,
		Details: details,
	}

	rb.logger.WithFields(logrus.Fields{
		"requestId": rb.requestID,
		"success":   false,
		"error":     code,
		"message":   message,
		"details":   details,
	}).Error("API error response")

	return rb.response
}

// ErrorWithStack 构建带堆栈的错误响应（仅开发环境）
func (rb *ResponseBuilder) ErrorWithStack(code, message string, details map[string]interface{}, stack string) *Response {
	rb.response.Success = false
	rb.response.Error = &ErrorInfo{
		Code:    code,
		Message: message,
		Details: details,
	}

	// 仅在开发环境包含堆栈信息
	if rb.isDev {
		rb.response.Error.Stack = stack
	}

	rb.logger.WithFields(logrus.Fields{
		"requestId": rb.requestID,
		"success":   false,
		"error":     code,
		"message":   message,
		"details":   details,
		"stack":     stack,
	}).Error("API error response with stack")

	return rb.response
}

// WriteJSON 将响应写入HTTP响应
func WriteJSON(w http.ResponseWriter, statusCode int, response interface{}) error {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(statusCode)

	encoder := json.NewEncoder(w)
	encoder.SetIndent("", "  ")
	return encoder.Encode(response)
}

// WriteSuccess 写入成功响应
func WriteSuccess(w http.ResponseWriter, data interface{}) error {
	return WriteJSON(w, http.StatusOK, data)
}

// WriteError 写入错误响应
func WriteError(w http.ResponseWriter, statusCode int, response *Response) error {
	return WriteJSON(w, statusCode, response)
}

// 预定义的错误代码
const (
	// 通用错误
	ErrCodeUnknown          = "UNKNOWN_ERROR"
	ErrCodeInvalidRequest   = "INVALID_REQUEST"
	ErrCodeValidationFailed = "VALIDATION_FAILED"
	ErrCodeNotFound         = "NOT_FOUND"
	ErrCodeConflict         = "CONFLICT"
	ErrCodeForbidden        = "FORBIDDEN"
	ErrCodeUnauthorized     = "UNAUTHORIZED"
	ErrCodeRateLimited      = "RATE_LIMITED"

	// 数据库相关错误
	ErrCodeDatabaseConnection = "DATABASE_CONNECTION_ERROR"
	ErrCodeDatabaseQuery      = "DATABASE_QUERY_ERROR"
	ErrCodeDatabaseTimeout    = "DATABASE_TIMEOUT"

	// 业务逻辑错误
	ErrCodeInvalidConfig     = "INVALID_CONFIG"
	ErrCodeOperationFailed   = "OPERATION_FAILED"
	ErrCodeResourceExhausted = "RESOURCE_EXHAUSTED"
)

// 预定义的错误消息
var ErrorMessages = map[string]string{
	ErrCodeUnknown:            "An unknown error occurred",
	ErrCodeInvalidRequest:     "Invalid request",
	ErrCodeValidationFailed:   "Validation failed",
	ErrCodeNotFound:           "Resource not found",
	ErrCodeConflict:           "Resource conflict",
	ErrCodeForbidden:          "Access forbidden",
	ErrCodeUnauthorized:       "Unauthorized",
	ErrCodeRateLimited:        "Rate limit exceeded",
	ErrCodeDatabaseConnection: "Database connection error",
	ErrCodeDatabaseQuery:      "Database query error",
	ErrCodeDatabaseTimeout:    "Database operation timeout",
	ErrCodeInvalidConfig:      "Invalid configuration",
	ErrCodeOperationFailed:    "Operation failed",
	ErrCodeResourceExhausted:  "Resource exhausted",
}

// GetErrorMessage 获取错误消息
func GetErrorMessage(code string) string {
	if msg, ok := ErrorMessages[code]; ok {
		return msg
	}
	return ErrorMessages[ErrCodeUnknown]
}
